import dayjs from "dayjs";

// 计算不明水率的函数
export function calculateWaterLossRate(level1Flow, level2Flow, precision = 2, unit = '%') {
    if (level1Flow === 0) return '0.00%';
    const waterLossRate = ((level1Flow - level2Flow) / level1Flow * 100);
    return `${waterLossRate.toFixed(precision)}${unit}`;
}

export function generateDateColumns(startTime, endTime, unit = 'day') {
    if (!['day', 'month', 'year'].includes(unit)) {
        throw new Error('Unit must be either "day", "month", or "year"');
    }

    const columns = [];
    let currentTime = startTime;

    const formatPatterns = {
        day: 'YYYY-MM-DD',
        month: 'YYYY-MM',
        year: 'YYYY'
    };

    while (currentTime < endTime) {
        columns.push(dayjs(currentTime).format(formatPatterns[unit]));
        currentTime = dayjs(currentTime).add(1, unit).valueOf();
    }

    return columns;
}/**
 * 格式化流量值，只有当error字段有值时才视为/
 * @param {any} value - 需要格式化的值
 * @param {string} error - 错误信息，如果有则表示/
 * @returns {string} 格式化后的字符串
 */
export function formatFlowValue(value) {


    // 值为null或undefined时显示/
    if (value === null || value === undefined) return '/';

    // 如果为百分比，则不格式化
    if (typeof value === 'string' && value.includes('%')) {
        return value;
    }

    // 确保数值格式化，包括0值
    const numValue = Number(value);
    return Number.isFinite(numValue) ? numValue.toFixed(2) : '/';
}

/**
 * 格式化读数值，只有当error字段有值时才视为/
 * @param {any} value - 需要格式化的值
 * @param {string} error - 错误信息，如果有则表示/
 * @returns {string} 格式化后的字符串
 */
export function formatReadingValue(value) {
    // 值为null或undefined时显示/
    if (value === null || value === undefined) return '/';

    // 处理数值，包括0值
    if (typeof value === 'number') {
        return value.toFixed(2);
    }

    // 尝试解析其他类型
    const numValue = Number(value);
    if (!isNaN(numValue)) {
        return numValue.toFixed(2);
    }

    // 最后的兜底，使用原始值的字符串表示
    return String(value);
}

/**
* 转换表计数据格式，只有当error字段有值时才视为/
* @param {Object} meter - 表计信息
* @param {Object} response - API响应数据
* @returns {Object} 转换后的数据
*/
export function transformMeterData(meter = {}, response = {}) {
    // 确保 meter 和 response 是对象
    if (!meter || typeof meter !== 'object') {
        meter = {};
    }
    if (!response || typeof response !== 'object') {
        response = {};
    }

    // 安全地获取聚合数据
    const data = Array.isArray(response.aggregated_data)
        ? response.aggregated_data
        : [];

    // 计算总流量，处理无效数值
    const totalFlow = data
        .reduce((sum, item) => {
            // 跳过有错误的数据
            if (item?.error) return sum;

            const value = parseFloat(item?.Value);
            return sum + (Number.isFinite(value) ? value : 0);
        }, 0)
        .toFixed(2);

    // 安全地获取启读数 - 只有错误时视为/
    const firstItem = data[0] || {};
    const beginValue = firstItem.begin;
    const hasError = !!firstItem.error;

    // 即使begin为"0"也是有效值
    const startReading = hasError ? '/' :
        (beginValue !== undefined && beginValue !== null) ?
            parseFloat(beginValue) : '/';
    const startError = hasError ? firstItem.error : '';

    // 将数据转换为扁平化结构，处理空值
    const flattenedData = {};
    data.forEach((item, index) => {
        const hasError = !!item?.error;

        // 处理使用量数据
        const valueStr = item?.Value;
        const value = valueStr !== undefined && valueStr !== null ? parseFloat(valueStr) : 0;
        flattenedData[`usage_${index}`] = hasError ? '/' : value;
        // 处理读数数据
        const endValue = item?.end;
        const reading = endValue !== undefined && endValue !== null ? parseFloat(endValue) : '/';
        flattenedData[`reading_${index}`] = hasError ? '/' : reading;
    });

    return {
        id: meter.id || '',
        meter_code: meter.meter_code || '',
        engine_id: meter.engine_id || '',
        meter_id: meter.meter_id || '',
        area_id: meter.area_id || '',
        level: meter.level || 0,
        installation_location: meter.installation_location || '',
        specification: meter.specification || '',
        supply_region: meter?.supply_region ?? '-',
        hasChild: Array.isArray(meter.children) && meter.children.length > 0,
        customChildren: Array.isArray(meter.children) ? meter.children : [],
        startReading: startReading,
        startError: startError,
        ...flattenedData,
        sum: totalFlow,
    };
}

/**
 * 将表计数据映射到表计列表中，包含数据验证和0值处理
 * @param {Array} meterList - 表计列表，每个表计对象包含一个唯一的 `id`
 * @param {Array} dataList - 乱序的表计数据列表，每个数据对象包含 `device_id`、`value` 和 `time`
 * @param {String} dataField - 映射数据的目标字段名
 * @param {Boolean} isAddTime - 是否添加时间字段
 * @param {String} date - 默认时间
 * @returns {Array} - 包含绑定数据的新的表计列表
 */
export const mapMeterData = (meterList, dataList, dataField, isAddTime = false, date) => {
    // 处理空数据列表的情况
    if (!Array.isArray(dataList) || dataList.length === 0) {
        return meterList.map(meter => ({
            ...meter,
            [dataField]: 0,
            ...(isAddTime ? { [`${dataField}_time`]: date } : null)
        }));
    }

    // 创建数据映射，使用 Map 结构存储最新的有效数据
    const dataMap = new Map();

    dataList.forEach((data) => {
        const { device_id, value, time } = data;

        // 验证数据有效性
        const numericValue = Number(value);
        if (device_id && !isNaN(numericValue) && time) {
            // 检查是否为负值
            const validValue = numericValue < 0 ? 0 : numericValue;

            // 如果 device_id 不存在或当前数据时间更新，则更新数据
            if (
                !dataMap.has(device_id) ||
                new Date(time) > new Date(dataMap.get(device_id).time)
            ) {
                dataMap.set(device_id, {
                    value: validValue,
                    time,
                    isValid: true
                });
            }
        }
    });

    // 遍历表计列表，将对应数据添加到表计中
    return meterList.map((meter) => {
        const meterData = dataMap.get(meter.id);

        // 构建返回对象
        const result = {
            ...meter,
            [dataField]: meterData?.isValid ? meterData.value : 0
        };

        // 添加时间字段（如果需要）
        if (isAddTime) {
            result[`${dataField}_time`] = meterData?.time || date;
        }

        return result;
    });
};


export const filterMetersByAreaId = (metersArray, targetAreaId) => {
    // 返回一个新数组，保持原数组的层级结构
    return metersArray.map((levelMeters, index) => {
        levelMeters = levelMeters.filter((meter) => {
            return meter.area_id === targetAreaId;
        });
        return levelMeters;
    });
};
export function processArrays(arrays) {
    // 基础验证
    if (!Array.isArray(arrays)) {
        return [];
    }
    if (!arrays?.length) {
        return [];
    }
    if (!arrays[0]?.length) {
        return [];
    }

    try {

        // 深拷贝第一个数组并确保Value为数字
        const result = arrays[0].map((item, index) => {

            // 验证item是否为对象且包含必要的属性
            if (!item || typeof item !== 'object' || !('Value' in item)) {
                throw new Error('Invalid item structure');
            }

            // 确保Value为数字，即使是字符串也能正确转换
            const numValue = typeof item.Value === 'string' ?
                parseFloat(item.Value) || 0 :
                (Number(item.Value) || 0);


            return {
                ...item,
                Value: numValue
            };
        });


        // 处理后续数组
        for (let i = 1; i < arrays.length; i++) {

            const currentArray = arrays[i];

            // 验证当前数组
            if (!Array.isArray(currentArray) || currentArray.length !== result.length) {
                continue;
            }

            currentArray.forEach((item, index) => {

                // 验证item结构
                if (!item || typeof item !== 'object' || !('Value' in item)) {
                    return;
                }

                // 转换并累加Value
                const numValue = typeof item.Value === 'string' ?
                    parseFloat(item.Value) || 0 :
                    (Number(item.Value) || 0);


                result[index].Value = (result[index].Value || 0) + numValue;

            });
        }

        return result;
    } catch (error) {

        return [];
    }
}
import { getMeterInfoApi, getMetersReportApi } from '@/api/meter';
import { getCarbonDataApi } from '@/api/carbon';
import { generateTimeConfig } from '@/utils/date';

/**
 * 获取资源使用统计数据，支持分片返回
 * @param {Object} params 查询参数
 * @param {string} params.range - 统计范围：'year' 或 'month'
 * @param {number} params.companyId - 公司ID
 * @param {Array} params.meters - 表计数据，如果不传则会自动获取
 * @param {Function} params.onProgress - 进度回调函数
 * @returns {Promise<Object>} 返回统计数据
 */
export const getResourceStats = async ({
    range,
    companyId,
    meters = null,
    onProgress = null
}) => {
    // 参数检查
    if (!companyId) {

        return {
            water: '0.00',
            electricity: '0.00',
            gas: '0.00',
            carbon: '0.00',
            carbonEmission: '0.00',
        };
    }

    // 使用统一时间配置
    let timeConfig;
    if (range === 'year') {
        timeConfig = generateTimeConfig('yearly', 0);
        timeConfig.interval = 'year';
    } else {
        timeConfig = generateTimeConfig('monthly', 0);
        timeConfig.interval = 'month';
    }

    const { start_time, end_time, interval } = timeConfig;

    try {
        // 如果没有传入meters，则获取表计数据
        let metersData = meters;
        if (!metersData || !Array.isArray(metersData) || metersData.length === 0) {
            try {
                const response = await getMeterInfoApi({
                    company_id: companyId,
                });

                if (!response || !response.data) {

                    metersData = [];
                } else {
                    metersData = response.data || [];
                }
            } catch (error) {

                metersData = [];
            }
        }

        // 筛选一级表
        const primaryMeters = {
            water: [],
            electricity: [],
            gas: []
        };

        if (Array.isArray(metersData)) {
            metersData.forEach(meter => {
                if (!meter) return;

                // 检查是否为一级表
                if (meter.parent_id === 0 || !meter.parent_id) {
                    switch (meter.type) {
                        case 1:
                            primaryMeters.water.push(meter);
                            break;
                        case 2:
                            primaryMeters.electricity.push(meter);
                            break;
                        case 3:
                            primaryMeters.gas.push(meter);
                            break;
                    }
                }
            });
        }

        // 创建获取单个资源类型数据的函数
        const fetchResourceData = async (type, resourceMeters) => {
            if (!resourceMeters || !Array.isArray(resourceMeters) || resourceMeters.length === 0) {
                if (onProgress && typeof onProgress === 'function') {
                    onProgress(type, '0.00');
                }
                return 0;
            }

            try {
                const report = await getMetersReportApi({
                    meters: resourceMeters,
                    start_time,
                    end_time,
                    interval
                });

                if (!report || !report.aggregated_data) {

                    if (onProgress && typeof onProgress === 'function') {
                        onProgress(type, '0.00');
                    }
                    return 0;
                }

                const usage = Array.isArray(report.aggregated_data)
                    ? report.aggregated_data.reduce((sum, item) => {
                        const value = item && typeof item.Value !== 'undefined' ? Number(item.Value) : 0;
                        return sum + (isNaN(value) ? 0 : value);
                    }, 0)
                    : 0;

                // 通过回调通知进度
                if (onProgress && typeof onProgress === 'function') {
                    onProgress(type, usage.toFixed(2));
                }

                return usage;
            } catch (error) {

                if (onProgress && typeof onProgress === 'function') {
                    onProgress(type, '0.00');
                }
                return 0;
            }
        };

        // 并发获取水电气数据
        const [waterUsage, electricityUsage, gasUsage] = await Promise.all([
            fetchResourceData('water', primaryMeters.water),
            fetchResourceData('electricity', primaryMeters.electricity),
            fetchResourceData('gas', primaryMeters.gas)
        ]);

        // 获取碳排放数据
        let carbonEmission = 0;
        try {
            const carbonResponse = await getCarbonDataApi({
                id: companyId,
                start_time,
                end_time,
                interval
            });

            if (carbonResponse && carbonResponse.code === 200 && Array.isArray(carbonResponse.data)) {
                const totalStandardCoal = carbonResponse.data.reduce((sum, item) => {
                    if (!item || !item.usage) return sum;

                    const usage = item.usage;
                    // 安全地获取并转换各项用量数据
                    const waterUsage = parseFloat(usage.water || 0) || 0;
                    const elecUsage = parseFloat(usage.elec || 0) || 0;
                    const gasUsage = parseFloat(usage.gas || 0) || 0;
                    const oilUsage = parseFloat(usage.oil || 0) || 0;
                    const heatUsage = parseFloat(usage.heat || 0) || 0;

                    return sum + waterUsage + elecUsage + gasUsage + oilUsage + heatUsage;
                }, 0);

                carbonEmission = totalStandardCoal * 0.68;
            } else {

            }
        } catch (error) {

        }

        // 通知碳排放数据
        if (onProgress && typeof onProgress === 'function') {
            onProgress('carbon', carbonEmission.toFixed(2));
        }

        // 返回完整统计结果
        return {
            water: waterUsage.toFixed(2),
            electricity: electricityUsage.toFixed(2),
            gas: gasUsage.toFixed(2),
            carbon: carbonEmission.toFixed(2),
            carbonEmission: carbonEmission.toFixed(2),
        };
    } catch (error) {

        return {
            water: '0.00',
            electricity: '0.00',
            gas: '0.00',
            carbon: '0.00',
            carbonEmission: '0.00',
        };
    }
};
/**
 * 获取每个区域最高级别的表计列表
 * @param {Array<Array<Object>>} metersArray - 按级别分组的二维表计数组，索引代表级别（0为最高级）
 * @param {Object} metersArray[][]} - 表计对象
 * @param {string} metersArray[][].area_id - 表计所属区域ID
 * @param {number} metersArray[][].id - 表计ID
 * @returns {Array<{area_id: string, meter_id: number[]}>} 每个区域的最高级表计信息数组
 * @example
 * const metersArray = [
 *   [{ id: 1, area_id: 'A1' }, { id: 2, area_id: 'A1' }], // 一级表
 *   [{ id: 3, area_id: 'A2' }], // 二级表
 *   [{ id: 4, area_id: 'A3' }]  // 三级表
 * ];
 * const result = getHighestLevelMetersPerArea(metersArray);
 * // returns: [
 * //   { area_id: 'A1', meter_id: [1, 2] },
 * //   { area_id: 'A2', meter_id: [3] },
 * //   { area_id: 'A3', meter_id: [4] }
 * // ]
 */
export function getHighestLevelMetersPerArea(metersArray) {
    // 如果数组为空或无效，返回空数组
    if (!metersArray || !metersArray.length) {
        return [];
    }

    // 记录每个区域已找到的最高级表计ID列表
    const highestLevelMeters = new Map();

    // 从最高级（索引0）开始遍历
    for (let level = 0; level < metersArray.length; level++) {
        const metersInLevel = metersArray[level];
        if (!metersInLevel) continue;

        // 遍历当前级别的所有表计
        metersInLevel.forEach(meter => {
            const areaId = meter.area_id;

            // 如果这个区域还没有记录过表计，创建一个新记录
            if (!highestLevelMeters.has(areaId)) {
                highestLevelMeters.set(areaId, {
                    area_id: areaId,
                    meters: [meter]
                });
            }
            // 如果已经有记录，且是在同一级别，则添加到meter_id数组中
            else if (level === Array.from(highestLevelMeters.keys())
                .find(key => key === areaId && highestLevelMeters.get(key))) {
                highestLevelMeters.get(areaId).meter_id.push(meter);
            }
        });
    }

    // 将Map转换为数组返回
    return Array.from(highestLevelMeters.values());
}
/**
 * 计算分时用量数据，通过计算相邻时间点的读数差值来得到每个时间点的用量
 * @param {Array<Object>} data - 输入的数据数组
 * @param {string} data[].time - 数据点的时间，格式为 'YYYY-MM-DD HH:mm'
 * @param {number} data[].value - 数据点的读数值
 * @returns {Array<Object>} 处理后的用量数据数组
 * @returns {string} returns[].time - 数据点的时间
 * @returns {number} returns[].value - 数据点的读数值
 * @returns {number} returns[].usage - 与前一个时间点相比的用量差值
 * @example
 * const data = [
 *   { time: '2024-01-01 10:00', value: 100 },
 *   { time: '2024-01-01 11:00', value: 150 },
 *   { time: '2024-01-01 12:00', value: 250 }
 * ];
 * const result = getDetailUsageData(data);
 * // 返回结果：
 * // [
 * //   { time: '2024-01-01 11:00', value: 150, usage: 50 },
 * //   { time: '2024-01-01 12:00', value: 250, usage: 100 }
 * // ]
 */
export const getDetailUsageData = (data) => {
    // 确保数据按时间排序
    const sortedData = data.sort((a, b) => new Date(a.time) - new Date(b.time));

    // 计算相邻读数之差，从第二个点开始
    const usageData = sortedData.slice(1).map((current, index) => {
        // 获取前一个数据点 (index + 1 是因为我们从slice(1)开始)
        const previous = sortedData[index];

        // 计算用量（当前读数减去前一个读数）
        const usage = current.value - previous.value;

        return {
            time: current.time,
            value: usage.toFixed(2),
        };
    });

    return usageData;
};

/**
 * 根据区域ID查找表计
 * @param {Array} meterTree - 表计树形结构
 * @param {number} areaId - 要查找的区域ID
 * @returns {Array} - 匹配区域ID的表计列表
 */
export function findMetersByAreaId(meterTree, areaId) {
    if (!meterTree || !Array.isArray(meterTree) || meterTree.length === 0) {
        return [];
    }

    if (!areaId && areaId !== 0) {
        return meterTree;
    }

    const result = [];

    // 递归搜索函数
    function searchMeters(meters, targetAreaId) {
        for (const meter of meters) {
            // 检查当前表计的区域ID是否匹配
            if (meter.area_id === targetAreaId) {
                result.push(meter);
            }

            // 如果有子表计，继续递归搜索
            if (meter.children && meter.children.length > 0) {
                searchMeters(meter.children, targetAreaId);
            }
        }
    }

    // 开始递归搜索
    searchMeters(meterTree, areaId);

    return result;
}

// 定义层级顺序
const LEVEL_ORDER = {
    'Ⅰ': 1, 'Ⅱ': 2, 'Ⅲ': 3, 'Ⅳ': 4, 'Ⅴ': 5, 'Ⅵ': 6, 'Ⅶ': 7, 'Ⅷ': 8, 'Ⅸ': 9, 'Ⅹ': 10, 'Ⅺ': 11
};

/**
 * 对表计列表进行排序
 * @param {Array} list - 表计列表
 * @returns {Array} - 排序后的表计列表
 */
export function sortMeterList(list) {
    return [...list].sort((a, b) => {
        const [levelA, seqA] = a.meter_code.split('-');
        const [levelB, seqB] = b.meter_code.split('-');

        // 获取层级顺序
        const levelOrderA = LEVEL_ORDER[levelA] || 0;
        const levelOrderB = LEVEL_ORDER[levelB] || 0;

        // 如果层级不同，按层级排序
        if (levelOrderA !== levelOrderB) {
            return levelOrderA - levelOrderB;
        }
        // 如果层级相同，按编号排序
        return parseInt(seqA) - parseInt(seqB);
    });
}

